#include "SparseMatrixGenerator.h"
#include "SparseMatrixReport.h"
#include "CompressedColumnStorage.h"
#include "SkylineStorage.h"
#include "matrix.h"
#include "timer.h"
#include <stdlib.h>
#include <math.h>


int main()
{
//    int dim = 1000;
//    SparseMatrixGenerator<double> generator(0,100);
//    DMatrix A(generator.generateRandomBandMatrix(dim,dim/10,0.1));
//    DVector b(generator.generateRandomVector(dim));
//    DVector Vo(dim);
//    Vo.zero();
//    DMatrix B(A *(~A));
//    DSkylineStorage SKAD(B);
//    DSkylineStorage SKAI(B);
//    Timer direct_solver_time;
//    DVector direct_solve_result(SKAD.solve(b));
//    cout << "\n";
//    cout << "Tempo de processamento método direto:\n";
//    cout << direct_solver_time.measure() << "\n";
//    Timer iterative_solver_time;
//    DVector iterative_solve_result(SKAI.PCGsolve(b,Vo,0.00001));
//    cout << "\n";
//    cout << "Tempo de processamento método iterativo: \n ";
//    cout << iterative_solver_time.measure() << "\n";
//    cout << "Erro entre os métodos \n ";

    
    

    
    SparseMatrixGenerator<double> generator(0,100);
    int m_dim = 150;
    DMatrix A(generator.generateRandomBandMatrix(m_dim,m_dim/5,0.2));
    DVector b(generator.generateRandomVector(m_dim));
    DMatrix B(A*(~A));
    DSkylineStorage SKD(B);
    DSkylineStorage SKI(B);
    DCompressedColumnStorage CSC(m_dim);
        for(int i = 0; i < m_dim; i++){
        for(int j = 0; j <= i; j++){
            if(B(j,i)!=0)
            CSC(j,i) = B(j,i);
        }
    }
    Timer direct_timer;
    DVector direct_solution(SKD.solve(b));
    cout << "Ellapsed Time for Direct Solution" << direct_timer.measure();
    cout<<"\n";
    Timer SKPCG_timer;
    DVector SKPCG_solution(SKI.PCGsolve(b,0.00001));
    cout << "Ellapsed Time for SKPCG\n" << SKPCG_timer.measure();
    cout<<"\n";
    Timer CSCPCG_timer;
    DVector CSCPCG_solution (CSC.PCGsolve(b));
    cout << "Ellapsed Time for CSCPCG\n" << CSCPCG_timer.measure();
    cout<<"\n\n";
    cout << (SKPCG_solution - direct_solution).maxV();
    
//    cout << "SKPCG error:\n";
//    SKPCG_solution -= direct_solution;
//    cout << "Max\n" << SKPCG_solution.maxV() << "\n";
//    cout << "Norm\n" << SKPCG_solution.norm()<< "\n\n";
//    CSCPCG_solution -= direct_solution;
//    cout << "CSCPCG error\n";
//    cout << "Max\n" << CSCPCG_solution.maxV() << "\n";
//    cout << "Norm\n" << CSCPCG_solution.norm();
           
//    SparseMatrixGenerator<int> generator(0,100);
//    CompressedColumnStorage<int> CCS(6,6);
//    Matrix<int> M = generator.generateRandomMatrix(6,0.5);
//    for(int i = 0; i < 6; i++){
//        for(int j = 0; j <= i; j++){
//            if(M(j,i)!=0)
//            CCS(j,i) = M(j,i);
//        }
//    }


    return 0;
}